package com.lebang.service.task.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.lebang.common.util.AmountUtil;
import com.lebang.common.util.ShowDateUtil;
import com.lebang.component.RedisClient;
import com.lebang.entity.LbbAppStore;
import com.lebang.entity.RequestHeaders;
import com.lebang.entity.member.LbbMember;
import com.lebang.entity.member.LbbMemberRecord;
import com.lebang.entity.task.LbbCommon;
import com.lebang.entity.task.LbbSoso;
import com.lebang.entity.task.LbbSosoWithBLOBs;
import com.lebang.entity.task.TaskScreenshot;
import com.lebang.example.LbbCommonExample;
import com.lebang.example.LbbSosoExample;
import com.lebang.mapper.*;
import com.lebang.model.TaskInitModel;
import com.lebang.model.enums.Booleans;
import com.lebang.model.enums.TaskEnableResultEnum;
import com.lebang.model.enums.buss.*;
import com.lebang.model.recordback.RecordCallBack;
import com.lebang.model.taskback.CommonCallBack;
import com.lebang.model.taskback.Detail;
import com.lebang.model.taskback.Record;
import com.lebang.model.vo.buss.TaskSearchVo;
import com.lebang.service.MemberNoticeService;
import com.lebang.service.TaskInRedisService;
import com.lebang.service.buss.MemberRecordService;
import com.lebang.service.buss.WalletService;
import com.lebang.service.task.TaskService;
import com.lebangweb.common.DateUtil;
import com.lebangweb.common.TextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.OutputStream;
import java.time.LocalDateTime;
import java.util.*;

/**
 * soso任务
 *
 * @author weizx
 * @className SosoService
 * @date 2018年7月20日 下午9:04:57
 */
@Service(value = "sosoTaskService")
public class SosoServiceImpl implements TaskService<LbbSosoWithBLOBs> {

    public static final String TASK_SOSO_AMOUNT = "task_soso_amount";

    @Autowired
    private MemberRecordService memberRecordService;
    @Autowired
    private WalletService walletService;
    @Autowired
    private LbbMemberRecordMapper lbbMemberRecordMapper;
    @Autowired
    private LbbSosoMapper lbbSosoMapper;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private LbbAppStoreMapper lbbAppStoreMapper;
    @Autowired
    private MemberNoticeService memberNoticeService;
    @Autowired
    private TaskInRedisService taskInRedisService;

    @Autowired
    private TaskScreenshotMapper taskScreenshotMapper;
    @Autowired
    private TaskTagRelationMapper taskTagRelationMapper;


    @Override
    public List<RecordCallBack> showListForApp(String memberId, Integer page, Integer size, String brand, Integer showHomePage, String imei, String params) {
        try {
            String check = null;
            Map<String, Object> obj = JSON.parseObject(params);
            if (obj != null) {
                Object object = obj.get("needCheck");

                if (object != null) {
                    check = object.toString();
                }
            }

            List<RecordCallBack> recordCallBacks = lbbMemberRecordMapper.appListForSoso(memberId, page, size, brand, showHomePage, check);
            for (Iterator<RecordCallBack> iterator = recordCallBacks.iterator(); iterator.hasNext(); ) {
                RecordCallBack vo = iterator.next();
                int o;
                String value = redisClient.hget(TASK_SOSO_AMOUNT, vo.getTaskId());
                if (value == null) {
                    o = 0;
                } else {
                    o = Integer.parseInt(value);
                    vo.setAmount(o);
                }
                if (vo.getAmount() == 0) {
                    iterator.remove();
                }
            }

            return recordCallBacks;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public List<LbbSosoWithBLOBs> taskList(Integer page, Integer limit) {
        Long row=null;
        if(!TextUtil.isEmpty(page,limit)){
            row=(long) ((page-1)*limit);
        }
        return lbbSosoMapper.selectListWithBLOBs(row,limit);
    }


    @Override
    public TaskEnableResultEnum checkTaskEnableDoForUser(String taskid, String imei, String userid) {
        LbbSosoWithBLOBs soso = lbbSosoMapper.selectByTaskId(taskid);
        if (soso == null) {
            return TaskEnableResultEnum.FAIL_NOT_EXITS;
        }
//        Date today = new Date();
//        Date tomr = DateUtil.getAfterDate(today, 1);
//        String strTomr = DateUtil.dateToString(tomr, "yyyy-MM-dd");
//        String strToday = DateUtil.dateToString(today, "yyyy-MM-dd");
//        // 同一天不能做同个应用包2次
//        int sameApp = lbbSosoMapper.hasCompletedSameAppToday(userid, imei, soso.getPackagename(), strToday, strTomr);
//        if (sameApp > 0) {
//            return TaskEnableResultEnum.FAIL_HAS_LOCK;
//        }
//        // 近30天不能做同个市场同个应用包2次
//        Date thirtyDayBefore = DateUtil.getBeginDate(today, 30);
//        String stime2 = DateUtil.dateToString(thirtyDayBefore, "yyyy-MM-dd");
//        int sameStoreApp = lbbSosoMapper.hasCompletedSameStoreApp(userid, imei, soso.getAppStore(), soso.getPackagename(), stime2, strTomr);
//
//        if (sameStoreApp > 0) {
//            return TaskEnableResultEnum.FAIL_HAS_LOCK;
//        }
        // 用户是否做过
        LbbMemberRecord record = lbbMemberRecordMapper.checkRecord(userid, taskid, TaskCategory.Soso.name(), imei, null);
        if (record != null) {
            return TaskEnableResultEnum.FAIL_HAS_TASK_NOT_END;
        }

        return TaskEnableResultEnum.SUCCESS;
    }


    @Override
    public RecordStatus pull(String memberId, LbbSosoWithBLOBs task, RequestHeaders requsetHeader, String orderId,String taskId) {
        int i = memberRecordService.insertRecord(TaskCategory.Soso, task.getTaskId(),
                memberId, requsetHeader, TaskStatus.WaitSumbit, "", "soso_" + task.getTaskId()
                        + "_" + requsetHeader.getUserid(), task.getNeedCheck(), 0, AmountUtil.checkAmount(task),
                task.getIncrease(), RewardType.Cash,task.getTitle());
        taskInRedisService.recordAdd(i);
        taskInRedisService.taskAmountSubtract(TASK_SOSO_AMOUNT, task.getTaskId());
        return RecordStatus.PULL_SUCCESS;
    }

    @Override
    public RecordStatus push(String memberId, LbbMemberRecord record, LbbSosoWithBLOBs task, String images, Integer sex) {
        try {
            if (null == images || "".equals(images)) {
                return RecordStatus.FAIL;
            } else {
                record.setResult(images);
                record.setStatus(TaskStatus.WaitCheckout);
                memberRecordService.updateRecord(record);
                String desc = "恭喜！任务“{title}”已提交，小姐姐正在努力审核!";
                desc = desc.replace("{title}", task.getTitle());
                memberNoticeService.notice(record, TaskCategory.Soso.getTitle(), desc);
            }
            if (record.getRedo() != null) {
                if (record.getRedo() == 0) {
                    taskInRedisService.recordDel(record.getId());
                }
            }
            return RecordStatus.PUSH_SUCCESS;
        } catch (Exception e) {
            return RecordStatus.ERROR;
        }
    }

    @Override
    public RecordStatus redo(String memberId, LbbMemberRecord record, LbbSosoWithBLOBs task) {
        if (record.getRedo() == null) {
            record.setRedo(0);
        }

        TaskScreenshot taskScreenshot = taskScreenshotMapper.selectByTaskId(task.getTaskId());
        if(taskScreenshot!=null){
            if(taskScreenshot.getFailTimes()!=-1&&taskScreenshot.getFailTimes()<=(record.getRedo())){
                return RecordStatus.REDO_MAX;
            }
        }

        record.setRedo(record.getRedo()+1);
        record.setStatus(TaskStatus.WaitSumbit);
        taskInRedisService.recordAdd(record.getId());
        record.setHurryTime(null);
        record.setSubmitTime(new Date());
        record.setCreateTime(new Date());
        record.setResult("");
        memberRecordService.updateRecord(record);
        return RecordStatus.REDO_SUCCESS;
    }

    @Override
    public RecordStatus urgentTask(String memberId, LbbMemberRecord record, LbbSosoWithBLOBs task) {
        List<String> id = new ArrayList<>(1);
        id.add(record.getId().toString());
        this.examineAndVerify(id, "", "任务成功", "",1);
        return RecordStatus.CALL_SUCCESS;
    }

    @Override
    public LbbSosoWithBLOBs taskInfoByTaskId(String taskId) {
        return lbbSosoMapper.selectByTaskId(taskId);
    }

    @Override
    public LbbSosoWithBLOBs taskInfoById(Integer id) {
        return lbbSosoMapper.selectByPrimaryKey(id.longValue());
    }

    @Override
    public CommonCallBack taskDetail(LbbSosoWithBLOBs task, LbbMemberRecord record, LbbMember memberId, String orderId) {
        CommonCallBack commonCallBack = new CommonCallBack();
        Record reco = new Record();
        Detail detail = new Detail();


        // 获取任务量完成情况
        String userStatus = UserStatus.Allow.name();

        // 如果做过不允许再做
        if (record != null) {
            userStatus = UserStatus.Disallow.name();
            if (!record.getStatus().equals(TaskStatus.WaitSumbit)) {
                if (!TextUtil.isEmpty(record.getResult())) {
                    commonCallBack.setMemberResult(JSONArray.parseArray(record.getResult()));
                }

            }
            commonCallBack.setType(record.getRewordType());
            commonCallBack.setUserMoney(record.getUserMoney());
        } else {
            record = new LbbMemberRecord();
            record.setCreateTime(new Date());
            record.setStatus(TaskStatus.None);
            commonCallBack.setUserMoney(AmountUtil.checkAmount(task));
            commonCallBack.setType(task.getType().getIndex());
        }
        // 获取任务量完成情况
        Integer amount = 0;
        // 获取任务量完成情况
        String count = redisClient.hget(TASK_SOSO_AMOUNT, task.getTaskId());
        if (count != null) {
            amount = Integer.parseInt(count);
        }
        // 返回结果

        LbbAppStore appStore = lbbAppStoreMapper.selectByCode(task.getAppStore());
        detail.setAmount(amount);
        detail.setUserStatus(userStatus);

        detail.setContents(JSONArray.parseArray(task.getContents()));

        detail.setOrderid(task.getContents());
        detail.setIcon(task.getIcon());
        detail.setLabel(task.getLabel());
        detail.setMedia(task.getMedia());
        detail.setTitle(task.getTitle());
        detail.setType(task.getType());
        detail.setSize(task.getSize());
        detail.setPackagename(task.getPackagename());
        detail.setAppStore(task.getAppStore());
        detail.setStoreAddress(appStore.getAddress());
        detail.setStoreIcon(appStore.getIcon());
        detail.setStoreName(appStore.getName());
        detail.setStoreName(appStore.getName());
        detail.setStorePackagename(appStore.getPackagename());
        detail.setMinutes(task.getMinutes());
        detail.setKeywords(task.getKeywords());
        detail.setRank(task.getRank());
        if (!TextUtil.isEmpty(task.getMission())) {
            List<String> stringList = Arrays.asList(task.getMission().split("#"));
            detail.setIsMission(true);
            detail.setMissionList(stringList);
        }
//        if(!TextUtil.isEmpty(task.getImages())){
//            detail.setImages(JSONArray.fromObject(task.getImages()));
//        }
        detail.setNeedCheck(task.getNeedCheck().name());
        reco.setEndTime(ShowDateUtil.afterMinute(record.getCreateTime(), 30));
        reco.setResult(record.getResult() == null ? "" : record.getResult());
        reco.setStatus(record.getStatus().name());
        reco.setRemark(record.getRemark());
        reco.setSubmitTime(record.getSubmitTime() == null ? "" : DateUtil.dateToString(record.getSubmitTime(), "yyyy-MM-dd HH:mm:ss"));

        commonCallBack.setCategory(TaskCategory.Soso.name());
        commonCallBack.setTaskid(task.getTaskId());
        commonCallBack.setTaskTime(task.getTaskTime());
        commonCallBack.setAuditTime(task.getAuditTime());
        commonCallBack.setRedoStatus(task.getRedo());
        if (task.getRedo() == null) {
            task.setRedo(0);
        }
        if (record.getHurryTime() == null) {

            commonCallBack.setHurryTime(0);
        } else {
            commonCallBack.setHurryTime(1);
        }
        if (record.getRedo() == null) {
            record.setRedo(0);
        }
        if (record.getSubmitTime() != null && record.getCreateTime() != null) {

            commonCallBack.setOverTime(ShowDateUtil.getDatePoor(record.getSubmitTime(), record.getCreateTime()));
        } else {
            commonCallBack.setOverTime("0");
        }
        commonCallBack.setRedocount(record.getRedo());
        commonCallBack.setRecord(reco);
        commonCallBack.setDetail(detail);
        return commonCallBack;
    }

    @Override
    public int insertTask(LbbSosoWithBLOBs task) {
        task.setHasDeleted(Booleans.False.name());
        task.setCreateTime(new java.util.Date());
        return lbbSosoMapper.insertSelective(task);
    }

    @Override
    public int updateTask(LbbSosoWithBLOBs task) {
        return lbbSosoMapper.updateByPrimaryKeySelective(task);
    }

    @Override
    public int deleteTask(LbbSosoWithBLOBs task) {
        task.setHasDeleted("True");
        return lbbSosoMapper.updateByPrimaryKeySelective(task);
    }

    @Override

    public int examineAndVerify(List<String> list, String tab, String status, String remark,Integer multiple) {
        try {
            List<LbbMemberRecord> recordList = lbbMemberRecordMapper.findCheckListByid(list);

            for (LbbMemberRecord record : recordList) {
                if (record.getStatus().equals(TaskStatus.CheckSuccess)) {
                    continue;
                }
                record.setStatus(TaskStatus.getByTitle(status));
                LbbSosoWithBLOBs task = this.taskInfoByTaskId(record.getTaskId());
                record.setStatus(TaskStatus.getByTitle(status));
                if (record.getStatus().equals(TaskStatus.CheckFailure)) {
                    record.setRemark(remark);
                }
                record.setCheckTime(new Date());
                memberRecordService.updateByPrimaryKeySelective(record);
                if (record.getStatus().equals(TaskStatus.CheckSuccess)) {
                    // 计算奖励
                    Integer amount;
                    if (record.getUserMoney().equals(0)) {
                        amount = AmountUtil.checkAmount(task);
                    } else {
                        amount = record.getUserMoney();
                    }
                    walletService.income(record.getMemberId(), record, TaskCategory.Soso, record.getTaskId(), task.getTitle(), amount);
                    task.setSuccessCount(task.getSuccessCount() + 1);
                    task.setTodayAmount(task.getTodayAmount() + 1);
                    //memberNoticeService.notice(record, task.getTitle(), "任务通知:提交的任务审核成功!");
                } else {
                    task.setFailCount(task.getFailCount() + 1);
                    memberNoticeService.notice(record, task.getTitle(), "对不起，您提交的不符合要求，审核失败！");

                }
                this.updateTask(task);

            }
            return 1;
        } catch (Exception e) {
            e.printStackTrace();

            return 0;
        }


    }

    @Override
    public Map<String, Object> list(TaskSearchVo vo) {
        int total = lbbSosoMapper.total(vo);
        List<Map<String, Object>> rows = lbbSosoMapper.pagging(vo);
        Map<String, Object> data = new HashMap<String, Object>(1);
        data.put("total", total);
        data.put("rows", rows);
        return data;
    }

    @Override
    public boolean starTaskAmount(LocalDateTime dateTime) {

        LbbSosoExample example = new LbbSosoExample();
        example.createCriteria().andStatusEqualTo("On").andHasDeletedEqualTo(Booleans.False.name());
        List<LbbSosoWithBLOBs> sosos = lbbSosoMapper.selectByExampleWithBLOBs(example);
        redisClient.del(TASK_SOSO_AMOUNT);


        List<TaskInitModel> taskInitModels = new ArrayList<>();
        sosos.forEach(vo -> {
            TaskInitModel model = new TaskInitModel();
            model.setTaskId(vo.getTaskId());
            model.setAmount(vo.getAmount());
            model.setSuccessTotal(vo.getSuccessCount());
            model.setTodayTotal(vo.getTodayAmount());
            model.setTotal(vo.getTotal());
            taskInitModels.add(model);
        });
        return taskInRedisService.taskInitByTaskModelList(TASK_SOSO_AMOUNT, taskInitModels, TaskCategory.Soso, dateTime);

    }

    @Override
    public Boolean exportTaskRecode(String taskId, OutputStream outputStream, List<TaskStatus> taskStatusList) {
        return null;
    }

    @Override
    public void releaseTask(LbbMemberRecord record) {
        //返还任务
        LbbSoso task1 = lbbSosoMapper.selectByTaskId(record.getTaskId());
        String title1 = "搜搜任务释放通知";
        String desc1 = "任务通知【" + task1.getTitle() + "】未在规定时间内完成,已被释放,请重新领取!";
        memberNoticeService.notice(record, title1, desc1);
        //返还任务
        String date = DateUtil.dateToString(new Date(), "yyyyMMdd");
        String creatdate = DateUtil.dateToString(record.getCreateTime(), "yyyyMMdd");
        if (date.equals(creatdate)) {
            taskInRedisService.taskAmountAdd(TASK_SOSO_AMOUNT, task1.getTaskId());
        }
    }

    /**
     * 重载单个任务并且校准成功数
     *
     * @param task
     * @return
     */
    @Override
    public boolean taskInitByTaskId(LbbSosoWithBLOBs task) {
        int i = lbbMemberRecordMapper.getsuccess(task.getTaskId(), TaskCategory.Soso.name());
        int k = lbbMemberRecordMapper.getfail(task.getTaskId(), TaskCategory.Soso.name());
        task.setSuccessCount(i);
        task.setFailCount(k);
        lbbSosoMapper.updateByPrimaryKeySelective(task);
        TaskInitModel model = new TaskInitModel();
        model.setTaskId(task.getTaskId());
        model.setAmount(task.getAmount());
        model.setSuccessTotal(task.getSuccessCount());
        model.setTodayTotal(task.getTodayAmount());
        model.setTotal(task.getTotal());
        return taskInRedisService.taskInitByTaskModel(TASK_SOSO_AMOUNT, model, LocalDateTime.now());
    }

}
